package xnum

import (
	"encoding/json"
	"time"
)

// 判断两个浮点数是否相等【json.Number时，f1和f2都会转化为float64进行计算】
//
//	f1	待比较的浮点数
//	f2	待比较的浮点数
func IsEqualFloat(f1, f2 any) bool {
	// 类型异常时的recover恢复，外层会直接返回false，此处恢复后仅作为错误记录
	defer func() {
		err := recover()
		if err, ok := err.(error); ok {
			if _default.PanicLog != nil {
				_default.PanicLog("类型判定错误", err)
			}
		}
	}()
	switch item := f1.(type) {
	case float32:
		return float64eq(float64(item), float64(f2.(float32)))
	case float64:
		return float64eq(item, f2.(float64))
	case int:
		return item == f2.(int)
	case uint:
		return item == f2.(uint)
	case int8:
		return item == f2.(int8)
	case uint8:
		return item == f2.(uint8)
	case int16:
		return item == f2.(int16)
	case uint16:
		return item == f2.(uint16)
	case int32:
		return item == f2.(int32)
	case uint32:
		return item == f2.(uint32)
	case int64:
		return item == f2.(int64)
	case uint64:
		return item == f2.(uint64)
	case json.Number:
		fl1, err := item.Float64()
		if err != nil {
			return false
		}
		fl2, err := f2.(json.Number).Float64()
		if err != nil {
			return false
		}
		return float64eq(fl1, fl2)
	case *json.Number:
		fl1, err := item.Float64()
		if err != nil {
			return false
		}
		fl2, err := f2.(*json.Number).Float64()
		if err != nil {
			return false
		}
		return float64eq(fl1, fl2)
	case time.Time:
		return item.Unix() == f2.(time.Time).Unix()
	}
	return false
}

// 判断浮点数是否相等
func float64eq(f1, f2 float64) bool {
	if f1 > f2 {
		return f1-f2 < FLOAT_EQUAL_MIN
	} else {
		return f2-f1 < FLOAT_EQUAL_MIN
	}
}
